package com.ssyx.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.ssyx.constant.GlobalConstant;
import com.ssyx.constant.RedisConstant;
import com.ssyx.enums.SkuType;
import com.ssyx.exception.SsyxException;
import com.ssyx.model.order.CartInfo;
import com.ssyx.model.product.SkuInfo;
import com.ssyx.product.ProductFeignClient;
import com.ssyx.result.ResultCodeEnum;
import com.ssyx.service.CartInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @program: ssyx-parent
 * @className: CartInfoServiceImpl
 * @description: 类
 * @data: 2024/3/19 14:17
 * @author: ihu
 * @version: 1.0
 **/

@Slf4j
@Service
public class CartInfoServiceImpl implements CartInfoService {
	
	@Resource
	private RedisTemplate<String, Object> redisTemplate;
	@Resource
	private ProductFeignClient productFeignClient;
	
	private String getCartKey(Long userId) {
		//定义key user:userId:cart
		return RedisConstant.USER_KEY_PREFIX + userId + RedisConstant.USER_CART_KEY_SUFFIX;
	}
	
	@Override
	public void addToCart(Long skuId, Long userId, Integer skuNum) {
		// 定义key user:userId:cart
		String cartKey = getCartKey(userId);
		//获取缓存对象
		BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
		CartInfo cartInfo = null;
		// 如果购物车中有该商品并且没有失效，则更新个数并选中 && cartInfo.getStatus().intValue() == 1
		if (Boolean.TRUE.equals(hashOperations.hasKey(skuId.toString()))) {
			cartInfo = hashOperations.get(skuId.toString());
			int currentSkuNum = GlobalConstant.INTEGER_ZERO;
			if (cartInfo != null) {
				currentSkuNum = cartInfo.getSkuNum() + skuNum;
			}
			if (currentSkuNum < GlobalConstant.INTEGER_ONE) {
				return;
			}
			
			//获取用户当前已经购买的sku个数，sku限量，每天不能超买
			//  添加购物车数量
			if (cartInfo != null) {
				cartInfo.setSkuNum(currentSkuNum);
			}
			//当天购买数量
			if (cartInfo != null) {
				cartInfo.setCurrentBuyNum(currentSkuNum);
			}
			//大于限购个数，不能更新个数
			if (cartInfo != null && currentSkuNum >= cartInfo.getPerLimit()) {
				throw new SsyxException(ResultCodeEnum.SKU_LIMIT_ERROR);
			}
			if (cartInfo != null) {
				cartInfo.setIsChecked(GlobalConstant.INTEGER_ONE);
			}
			if (cartInfo != null) {
				cartInfo.setUpdateTime(new Date());
			}
		} else {
			//第一次添加只能添加一个
			skuNum = GlobalConstant.INTEGER_ONE;
			// 当购物车中没用该商品的时候，则直接添加到购物车！insert
			cartInfo = new CartInfo();
			// 购物车数据是从商品详情得到 {skuInfo}
			SkuInfo skuInfo = productFeignClient.getSkuInfo(skuId);
			if (skuInfo == null) {
				throw new SsyxException(ResultCodeEnum.DATA_ERROR);
			}
			cartInfo.setSkuId(skuId);
			cartInfo.setCategoryId(skuInfo.getCategoryId());
			cartInfo.setSkuType(skuInfo.getSkuType());
			cartInfo.setIsNewPerson(skuInfo.getIsNewPerson());
			cartInfo.setUserId(userId);
			cartInfo.setCartPrice(skuInfo.getPrice());
			cartInfo.setSkuNum(skuNum);
			cartInfo.setCurrentBuyNum(skuNum);
			cartInfo.setSkuType(SkuType.COMMON.getCode());
			cartInfo.setPerLimit(skuInfo.getPerLimit());
			cartInfo.setImgUrl(skuInfo.getImgUrl());
			cartInfo.setSkuName(skuInfo.getSkuName());
			cartInfo.setWareId(skuInfo.getWareId());
			cartInfo.setIsChecked(GlobalConstant.INTEGER_ONE);
			cartInfo.setStatus(GlobalConstant.INTEGER_ONE);
			cartInfo.setCreateTime(new Date());
			cartInfo.setUpdateTime(new Date());
		}
		// 更新缓存
		if (cartInfo != null) {
			hashOperations.put(skuId.toString(), cartInfo);
		}
		// 设置过期时间
		setCartKeyExpire(cartKey);
	}
	
	@Override
	public void deleteCart(Long skuId, Long userId) {
		BoundHashOperations<String, String, CartInfo> boundHashOps =
				this.redisTemplate.boundHashOps(this.getCartKey(userId));
		//  判断购物车中是否有该商品！
		if (Boolean.TRUE.equals(boundHashOps.hasKey(skuId.toString()))) {
			boundHashOps.delete(skuId.toString());
		}
	}
	
	@Override
	public void deleteAllCart(Long userId) {
		String cartKey = getCartKey(userId);
		//获取缓存对象
		BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
		Objects.requireNonNull(hashOperations.values()).forEach(cartInfo -> {
			hashOperations.delete(cartInfo.getSkuId().toString());
		});
	}
	
	@Override
	public void batchDeleteCart(List<Long> skuIdList, Long userId) {
		String cartKey = getCartKey(userId);
		//获取缓存对象
		BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
		skuIdList.forEach(skuId -> {
			hashOperations.delete(skuId.toString());
		});
	}
	
	@Override
	public List<CartInfo> getCartList(Long id) {
		// 返回的集合对象
		List<CartInfo> cartInfoList = new ArrayList<>();
		if (StringUtils.isEmpty(id)) return cartInfoList;
		BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(getCartKey(id));
		// 获取数据
		cartInfoList = hashOperations.values();
		if (!CollectionUtils.isEmpty(cartInfoList)) {
			// 购物车列表显示有顺序：按照商品的更新时间 降序
			cartInfoList.sort((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime()));
		}
		return cartInfoList;
	}
	
	@Override
	public void checkCart(Long userId, Integer isChecked, Long skuId) {
		String cartKey = getCartKey(userId);
		BoundHashOperations<String, String, CartInfo> boundHashOps = this.redisTemplate.boundHashOps(cartKey);
		CartInfo cartInfo = boundHashOps.get(skuId.toString());
		if (cartInfo != null) {
			cartInfo.setIsChecked(isChecked);
			boundHashOps.put(skuId.toString(), cartInfo);
			setCartKeyExpire(cartKey);
		}
	}
	
	@Override
	public void checkAllCart(Long userId, Integer isChecked) {
		String cartKey = getCartKey(userId);
		BoundHashOperations<String, String, CartInfo> boundHashOps = this.redisTemplate.boundHashOps(cartKey);
		Objects.requireNonNull(boundHashOps.values()).forEach(cartInfo -> {
			cartInfo.setIsChecked(isChecked);
			boundHashOps.put(cartInfo.getSkuId().toString(), cartInfo);
		});
		setCartKeyExpire(cartKey);
	}
	
	@Override
	public void batchCheckCart(List<Long> skuIdList, Long userId, Integer isChecked) {
		String cartKey = getCartKey(userId);
		//获取缓存对象
		BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
		skuIdList.forEach(skuId -> {
			CartInfo cartInfo = hashOperations.get(skuId.toString());
			if (cartInfo != null) {
				cartInfo.setIsChecked(isChecked);
			}
			if (cartInfo != null) {
				hashOperations.put(cartInfo.getSkuId().toString(), cartInfo);
			}
		});
	}
	
	@Override
	public List<CartInfo> getCartCheckedList(Long userId) {
		BoundHashOperations<String, String, CartInfo> boundHashOps =
				this.redisTemplate.boundHashOps(this.getCartKey(userId));
		return Objects.requireNonNull(boundHashOps.values()).stream().filter((cartInfo) -> cartInfo.getIsChecked().intValue() == GlobalConstant.INTEGER_ONE).collect(Collectors.toList());
	}
	
	@Override
	public void deleteCartChecked(Long userId) {
		List<CartInfo> cartInfoList = this.getCartCheckedList(userId);
		List<Long> skuIdList = cartInfoList.stream().map(CartInfo::getSkuId).collect(Collectors.toList());
		//获取缓存对象
		BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(getCartKey(userId));
		skuIdList.forEach(skuId -> hashOperations.delete(skuId.toString()));
	}
	
	//  设置key 的过期时间！
	private void setCartKeyExpire(String cartKey) {
		redisTemplate.expire(cartKey, RedisConstant.USER_CART_EXPIRE, TimeUnit.SECONDS);
	}
}
